\chapter{Concurrency in Vorpal}
\label{Concurrency}

\section{Basics}

The non-blocking concurrency model in Vorpal is based on creating separate virtual machine instances that communicate by sending objects to each other.  Additional Vorpal processes are created by calling \verb-spawn- on an object, which returns a Process object.  Messages are passed by calling methods on that Process.  Here's a simple process that prints the number of messages it has received:
\vorpal
counter = new()
counter.count = 0
counter.receive = new()
counter.receive.report = method(label){
        .count = .count + 1
        label + 'I have received ' + .count + ' messages'.print()
}

id = counter.spawn()
counter.count = 11

for(i = 0, i < 2, i = i + 1){
        '---'.print()
        id.report('' + i + '. ')
}
\end{lstlisting}

\noindent The output of this program is completely deterministic:
\begin{verbatim}
---
---
0. I have received 1 messages
1. I have received 2 messages
\end{verbatim}

There are actually two Vorpal processes in this example.  The main process which was created by the host program to execute the source code and the process created by \verb-counter.spawn()-.  Vorpal uses an event driven messaging model where each process acts on all its incoming messages and {\em then} its outgoing messages are transmitted.  This semi-synchonous model is why the main process is guaranteed to print the \verb|"---"| lines before the messages it sends to \verb-id- are received.

Also, note that \verb-counter.count = 11- (line 10) has no effect.  The new process has already been spawned with the original value (set in line 3), so the counter in use by the process starts at zero.  To receive messages, the process object must implement methods in its \verb-receive- slot (lines 3-7).  This restriction prevents processes from calling arbitrary methods in other processes.

\section{Valid Messages and Process Objects}

\begin{itemize}
\item Only serializable objects can be sent, published, or used to create processes.
\item This includes spawned objects and {\em all} arguments used in events.
\item Complex objects (with many sub-parts) are allowed; in fact they are necessary.
\item Loops in the data structures are not a problem.  Example: \verb-x.a = x-
\item These objects can be serialized: Object, Process, String, Number, Code, True, False, and None
\item All spawned and passed objects are {\em copied} at the moment the send is issued.
\end{itemize}

\section{The Update Model}

\begin{itemize}
\item Each update cycle, Vorpal allows all processes to act on each event in their incoming queue (in FIFO order).
\item Sent messages and spawns are placed in an outgoing queue and sent once the update cycle is complete for {\em all} local processes.
\item Processes may be run in parallel by the Vorpal system.  The maximum number of truly parallel executions is determined by your CPU and the pool size used to configure Vorpal (see option -p in the Vorpal shell).
\item Effectively, all processes are run in parallel since they can't interact during the update phase.
\end{itemize}

\section{API}

\begin{itemize}
\item \verb-obj.process()- : returns Process object for the currently running process
\item \verb-obj.spawn()- : creates a process by copying \verb-obj-, returns a Process, immediately usable
\item \verb-id.kill()- see Spawn and Kill section
\item \verb-.process().later()- : sends the current event to the back of the incoming event queue (only usable on the current process).
\item \verb-.process().redirect(id)- redirects a message to another process (only usable on the current process).  Special result slot privileges are lost (see Contingent Messages section)
\item \verb-obj.publish()- : change your own state; the last published state in the update cycle takes effect
\item \verb-id.state()- : read another the state of another Process
\end{itemize}

\section{Publish and State}

\begin{itemize}
\item Each process can expose state to other processes with \verb-obj.publish()-
\item Any process can read the published state with \verb-id.state()-
\item The published state is changed after all processes update.
\end{itemize}

\section{Spawn and Kill}

\begin{itemize}
\item When you spawn a process an useable Process object is immediately returned.
\item The process is actually not created until the outgoing queue of messages is sent, but since they are sent in order, there is no danger of communicating with a non-existent process.
\item Currently processes are difficult to safely kill if they are shared. 
\item \verb-id.kill()- removes/destoyes the Process when it {\em receives} the kill message. 
\item Any messages sent before \verb-kill- by the sender of \verb-kill- will get processed.
\item Messages from other senders may not arrive in time to get processed.
\item Sending a message to a process that does not exist is a runtime error.
\item Processes are not garbage collected (\verb-kill- simply removes them), though this may be added in the future.
\end{itemize}

\section{Contingent Messages and Replies}

\begin{itemize}
\item Contingent messages are a way of expressing sequential behaviour.
\item Contingent messages are attached to another message and are sent when that message is handled.
\item Contingent messages can be connect arbitrarily.
\item All messages directly attached to the current event are put in the outgoing queue after the event has been processed.
\item If the receiver returns a value other than \verb-self-, then the first \verb-none- parameter in each contingent message is replaced by the returned value from the receiver.
\item They are created using this syntax: \verb|id.f(1, 2) -> id2.g(3, none)|
\item In the above example, \verb-id2- will get the \verb-g- message with the second parameter replaced by the result of \verb-id.f(1, 2)-.
\item The above example is comparable to the sequential code: \verb-id2.g(3, id.f(1, 2))-
\item Parallel contingent messages can be attached.  These messages will be sent at the same time, and each can have sequential messages attached.  \\
\verb"id.f(1, 2) -> ( id2.g(3, none) || id3.f(none) )"
\end{itemize}

\section{Changing Receiving Behaviour}

\begin{itemize}
\item Simply change the \verb-receive- and the \verb-result- slots of your process.
\item If a handler is not defined for an incoming message (other than \verb-kill-), then a runtime error occurs.
\item Handlers can defer and redirect messages.
\item Deferring a message places it in the back of the queue.
\item Redirecting a message sends it to another process (without permission to trigger \verb-result- events).
\item A message can be {\em both} deferred and redirected simultaneously.
\item defer: \verb-receive.f = method(){ .process().later() }-
\item redirect: \verb-receive.f = method(){ .process().redirect(id) }-
\end{itemize}


